﻿//-----------------------------------------------------------------------
// <copyright file="TwiterBootstrapExtensions.cs" company="deixei.com">
//     Copyright (c) deixei.com. All rights reserved.
// </copyright>
// <author>Marcio Parente</author>
//---------------------------------------------------------------------
namespace Deixei.Web
{
    using Deixei;
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
    using System.Web.Script.Serialization;

    /// <summary>
    /// Twiter Bootstrap Extensions - http://twitter.github.com/bootstrap
    /// </summary>
    public static class TwiterBootstrapExtensions
    {
        public static MvcHtmlString NavBar(this HtmlHelper htmlHelper, string html)
        {
            return new TagBuilder("div").AddClass("navbar").Html(html).ToHtmlString();
        }

        public static MvcHtmlString InnerNavBar(this HtmlHelper htmlHelper, string html)
        {
            return new TagBuilder("div").AddClass("navbar-inner").Html(html).ToHtmlString();
        }

        public static MvcHtmlString Brand(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string areaName = "")
        {
            //<a class="brand" href="#">Project name</a>
            TagBuilder item = new TagBuilder("a");

            string href = "#";

            item.AddClass("brand");
            item.Attribute("href", href);
            item.Text(linkText);
            //TODO: Erro
            MvcHtmlString x = GeneralExtensions.Link(htmlHelper, linkText, actionName, controllerName, areaName);
            

            return item.ToHtmlString();
        }

        public static MvcHtmlString Caret(this HtmlHelper htmlHelper)
        {
            //<span class="caret"></span>
            return new TagBuilder("span").AddClass("caret").ToHtmlString();
        }

        public static MvcHtmlString Divider(this HtmlHelper htmlHelper)
        {
            //<li class="divider"></li>
            return new TagBuilder("li").AddClass("divider").ToHtmlString();
        }

        //Dropdown menus
//<div class="dropdown">
//<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
//Action
//<span class="caret"></span>
//</a>
        //1.<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu">
        //2.  <li><a tabindex="-1" href="#">Action</a></li>
        //3.  <li><a tabindex="-1" href="#">Another action</a></li>
        //4.  <li><a tabindex="-1" href="#">Something else here</a></li>
        //5.  <li class="divider"></li>
        //6.  <li><a tabindex="-1" href="#">Separated link</a></li>
        //7.</ul>
//</div>

        public static MvcHtmlString DropdownMenu(this HtmlHelper htmlHelper,string buttonLabel, params object[] children)
        {
            TagBuilder wraper = new TagBuilder("div");
            wraper.AddClass("dropdown");

            TagBuilder link = new TagBuilder("div");
            link.AddClass("btn dropdown-toggle");
            link.Attribute("data-toggle", "dropdown");
            link.Attribute("href", "#");
            link.Text(buttonLabel + " ");
            link.Append(htmlHelper.Caret());

            wraper.Append(link);


            TagBuilder item = new TagBuilder("ul");
            item.AddClass("dropdown-menu");
            item.Attribute("role", "menu");
            item.Attribute("aria-labelledby", "dropdownMenu");

            foreach ( var childitem in children )
            {
                item.Append(childitem);
            }

            wraper.Append(item);

            return wraper.ToHtmlString();
        }

        //<li><a tabindex="-1" href="#">Action</a></li>
        public static MvcHtmlString DropdownMenuItem(this HtmlHelper htmlHelper, string linkName, string url, bool isActive = false)
        {
            TagBuilder tag = new TagBuilder("li");
            if ( isActive )
            {
                tag.AddClass("active");
            }
            TagBuilder link = new TagBuilder("a");
            link.Attribute("tabindex", "-1");
            link.Attribute("href", url);
            link.Text(linkName);

            tag.Append(link);

            return tag.ToHtmlString();
        }

        // Sub menus on dropdowns
        //<li class="dropdown-submenu">
        //  <a tabindex="-1" href="#">More options</a>
        //  <ul class="dropdown-menu">
        //    ...
        //  </ul>
        //</li>

        public static MvcHtmlString DropdownSubMenu(this HtmlHelper htmlHelper, string subMenuName, params object[] children)
        {
            TagBuilder item = new TagBuilder("li");
            item.AddClass("dropdown-submenu");

            TagBuilder submenu = new TagBuilder("ul");
            submenu.AddClass("dropdown-menu");

            
            TagBuilder link = new TagBuilder("a");
            link.Attribute("tabindex", "-1");
            link.Attribute("href", "#");
            link.Text(subMenuName);

            item.Append(link);

            foreach ( var childitem in children )
            {
                submenu.Append(childitem);
            }

            item.Append(submenu);

            return item.ToHtmlString();
        }

        // ButtonToolbar
        //1.<div class="btn-toolbar">
        //2.  <div class="btn-group">
        //3.    ...
        //4.  </div>
        //5.</div>
        public static MvcHtmlString ButtonToolbar(this HtmlHelper htmlHelper, params object[] children)
        {
            TagBuilder item = new TagBuilder("div");
            item.AddClass("btn-toolbar");
            foreach (var childitem in children)
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        // ButtonGroup
        public static MvcHtmlString ButtonGroup(this HtmlHelper htmlHelper, params object[] children)
        {
            TagBuilder item = new TagBuilder("div");
            item.AddClass("btn-group");
            foreach (var childitem in children)
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        public static MvcHtmlString ButtonIcon(this HtmlHelper htmlHelper, Icon icon, string onClick = "", params object[] children)
        {
            return Button(htmlHelper, "", onClick, icon, ButtonSize.Default, ButtonStyle.Default, ButtonProp.Default, children);
        }

        public static MvcHtmlString Button(this HtmlHelper htmlHelper, string buttonName, string onClick = "", params object[] children)
        {
            return Button(htmlHelper, buttonName, onClick, Icon.Default ,ButtonSize.Default, ButtonStyle.Default, ButtonProp.Default, children);
        }

        // Button
        // <button class="btn">1</button>
        // <button data-bind="click: incrementClickCounter">Click me</button>
        // http://knockoutjs.com/documentation/click-binding.html
        public static MvcHtmlString Button(this HtmlHelper htmlHelper, string buttonName, string onClick = "",
            Icon icon = Icon.Default,
            ButtonSize buttonSize = ButtonSize.Default,
            ButtonStyle buttonStyle = ButtonStyle.Default,
            ButtonProp buttonProp = ButtonProp.Default,
            params object[] children)
        {
            TagBuilder item = new TagBuilder("button");
            item.AddClass("btn");
            // TODO
            item.AddClass(buttonSize.ToCss());
            item.AddClass(buttonStyle.ToCss());
            item.AddClass(buttonProp.ToCss());

            if ( !string.IsNullOrEmpty(onClick) )
            {
                item.Attribute("data-bind", "click: " + onClick);
            }

            if (icon != Icon.Default)
            {
                item.Text(buttonName + " ");
                item.Append(htmlHelper.Icon(icon));
            }
            else
            {
                item.Text(buttonName);
            }
            foreach (var childitem in children)
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        //1.<div class="tabbable"> <!-- Only required for left/right tabs -->
        //2.  <ul class="nav nav-tabs">
        //3.    <li class="active"><a href="#tab1" data-toggle="tab">Section 1</a></li>
        //4.    <li><a href="#tab2" data-toggle="tab">Section 2</a></li>
        //5.  </ul>
        //6.  <div class="tab-content">
        //7.    <div class="tab-pane active" id="tab1">
        //8.      <p>I'm in Section 1.</p>
        //9.    </div>
        //10.    <div class="tab-pane" id="tab2">
        //11.      <p>Howdy, I'm in Section 2.</p>
        //12.    </div>
        //13.  </div>
        //14.</div>
        public static MvcHtmlString TabGroup(this HtmlHelper htmlHelper, params object[] children)
        {
            // NOT GOOD
            TagBuilder item = new TagBuilder("div");
            item.AddClass("tabbable");

            foreach (var childitem in children)
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        public static MvcHtmlString TabHeader(this HtmlHelper htmlHelper, params object[] tabs)
        {
            TagBuilder item = new TagBuilder("div");
            item.AddClass("nav");
            item.AddClass("nav-tabs");

            foreach (var childitem in tabs)
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        public static MvcHtmlString TabContents(this HtmlHelper htmlHelper, params object[] tabPanes)
        {
            TagBuilder item = new TagBuilder("div");
            item.AddClass("tab-content");
            foreach (var childitem in tabPanes)
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        // <li class="active"><a href="#tab1" data-toggle="tab">Section 1</a></li>
        // Tab
        public static MvcHtmlString Tab(this HtmlHelper htmlHelper, string id, string name, bool isActive = false)
        {
            TagBuilder item = new TagBuilder("li");
            if (isActive)
            {
                item.AddClass("active");
            }

            TagBuilder link = new TagBuilder("a");
            link.Attribute("href","#" + id);
            link.Attribute("data-toggle", "tab");
            link.Text(name);

            item.Append(link);

            return item.ToHtmlString();
        }

        //7.    <div class="tab-pane active" id="tab1">
        //8.      <p>I'm in Section 1.</p>
        //9.    </div>
        // TabPane
        public static MvcHtmlString TabPane(this HtmlHelper htmlHelper, string id, bool isActive = false, params object[] children)
        {
            TagBuilder item = new TagBuilder("div");
            item.AddClass("tab-pane");
            if (isActive)
            {
                item.AddClass("active");
            }
            item.Attribute("id", id);

            foreach (var childitem in children)
            {
                item.Append(childitem);
            }

            return item.ToHtmlString();
        }



        //<ul class="nav">
        //<li class="dropdown">
        //    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Areas <b class="caret"></b></a>
        //    <ul class="dropdown-menu">
        //      <li class="nav-header">Start</li>
        //      <li><a href="#">Home</a></li>
        //      <li class="nav-header">Areas</li>
        //      <li><a href="#">Customer Service</a></li>
        //      <li><a href="#">Marketing</a></li>
        //      <li><a href="#">Sales</a></li>
        //      <li><a href="#">Social</a></li>
        //      <li class="divider"></li>
        //      <li class="nav-header">Demos</li>
        //      <li><a href="#">Admin</a></li>
        //      <li><a href="#">Demos</a></li>
        //      <li><a href="#">Marcio Parente</a></li>
        //    </ul>
        //  </li>
        //</ul>
        public static MvcHtmlString AreasDropdownMenu(this HtmlHelper htmlHelper, string activeAreaName = "", params object[] children)
        {
            CommonUtil.CheckForNull(activeAreaName, "activeAreaName");
            TagBuilder tag = new TagBuilder("ul");
            tag.AddClass("nav");

            tag.Append(DropdownListItem(htmlHelper, "Areas",
                NavHeader(htmlHelper, "Start"),
                DropdownMenuItem(htmlHelper, "Home", "/", ( activeAreaName == "Home" || activeAreaName == "" )),
                NavHeader(htmlHelper, "Areas"),
                DropdownMenuItem(htmlHelper, "Customer Service", "/CustomerService/Accounts/Index", ( activeAreaName == "CustomerService" )),
                DropdownMenuItem(htmlHelper, "Marketing", "/Marketing/Segmentation/Index", ( activeAreaName == "Marketing" )),
                DropdownMenuItem(htmlHelper, "Sales", "/Sales/Customer/Index", ( activeAreaName == "Sales" )),
                DropdownMenuItem(htmlHelper, "Social", "/Social/Facebook/Index", ( activeAreaName == "Social" )),
                Divider(htmlHelper),
                NavHeader(htmlHelper, "Demos"),
                DropdownMenuItem(htmlHelper, "Admin", "/Admin/Portfolio/Index", ( activeAreaName == "Admin" )),
                DropdownMenuItem(htmlHelper, "Demos", "/Demos/Bootstrap/Components", ( activeAreaName == "Demos" )),
                DropdownMenuItem(htmlHelper, "Marcio Parente", "/MarcioParente/CV/Index", ( activeAreaName == "MarcioParente" ))
                ));
            
            return tag.ToHtmlString();
        }

        //<a href="#" class="dropdown-toggle" data-toggle="dropdown">Areas <b class="caret"></b></a>
        public static MvcHtmlString DropdownToggle(this HtmlHelper htmlHelper, string name = "")
        {
            TagBuilder link = new TagBuilder("a");
            link.AddClass("dropdown-toggle");
            link.Attribute("data-toggle", "dropdown");
            link.Attribute("href", "#");
            link.Text(name + " ");
            link.Append(htmlHelper.Caret());
            return link.ToHtmlString();
        }


        //<li class="nav-header">Start</li>
        public static MvcHtmlString NavHeader(this HtmlHelper htmlHelper, string headerName = "")
        {
            TagBuilder tag = new TagBuilder("li");
            tag.AddClass("nav-header");
            tag.Text(headerName);
            return tag.ToHtmlString();
        }

        //<li class="dropdown">
        //DropdownToggle    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Areas <b class="caret"></b></a>
        //    <ul class="dropdown-menu">
        // ...
        //    </ul>
        //  </li>
        public static MvcHtmlString DropdownListItem(this HtmlHelper htmlHelper, string name = "", params object[] children)
        {
            TagBuilder dropdownTag = new TagBuilder("li");
            dropdownTag.AddClass("dropdown");

            TagBuilder dropdownMenuTag = new TagBuilder("ul");
            dropdownMenuTag.AddClass("dropdown-menu");

            foreach ( var childitem in children )
            {
                dropdownMenuTag.Append(childitem);
            }

            dropdownTag.Append(DropdownToggle(htmlHelper, name));
            dropdownTag.Append(dropdownMenuTag);


            return dropdownTag.ToHtmlString();
        }



        //<a href="#PageInformation" role="button" data-toggle="modal">Page information modal</a>
        public static MvcHtmlString DialogBoxLink(this HtmlHelper htmlHelper, string DialogBoxName, string Title)
        {
            CommonUtil.CheckStringForNullOrEmpty(DialogBoxName, "DialogBoxName");
            CommonUtil.CheckStringForNullOrEmpty(Title, "Title");

            var sb = new StringBuilder();
            sb.AppendFormat(@"<a href=""#{0}"" role=""button"" data-toggle=""modal"">{1}</a>", DialogBoxName, Title);
            return MvcHtmlString.Create(sb.ToString());
        }

        public static MvcHtmlString DialogBoxButton(this HtmlHelper htmlHelper, string DialogBoxName, string Title,
    Icon icon = Icon.Default,
    ButtonSize buttonSize = ButtonSize.Default,
    ButtonStyle buttonStyle = ButtonStyle.Default,
    ButtonProp buttonProp = ButtonProp.Default,
    params object[] children)
        {

            CommonUtil.CheckStringForNullOrEmpty(DialogBoxName, "DialogBoxName");
            CommonUtil.CheckStringForNullOrEmpty(Title, "Title");

            TagBuilder item = new TagBuilder("a");
            item.AddClass("btn");
            // TODO
            item.AddClass(buttonSize.ToCss());
            item.AddClass(buttonStyle.ToCss());
            item.AddClass(buttonProp.ToCss());

            item.Attribute("role", "button");
            item.Attribute("data-toggle", "modal");
            item.Attribute("href", "#" + DialogBoxName);

            if ( icon != Icon.Default )
            {
                item.Text(Title + " ");
                item.Append(htmlHelper.Icon(icon));
            }
            else
            {
                item.Text(Title);
            }
            foreach ( var childitem in children )
            {
                item.Append(childitem);
            }
            return item.ToHtmlString();
        }

        public static MvcHtmlString DialogBox(this HtmlHelper htmlHelper, string Name, string Title, params object[] children)
        {
            var sb = new StringBuilder();
            //sb.AppendLine(string.Format("var {0} = {{ }};", namespaceName.Trim()));
            sb.AppendFormat(@"<div class=""modal hide"" id=""{0}"" tabindex=""-1"" role=""dialog"" aria-labelledby=""{0}ModalLabel"" aria-hidden=""true"">", Name);
            sb.AppendLine(@"  <div class=""modal-header"">");
            sb.AppendLine(@"    <button type=""button"" class=""close"" data-dismiss=""modal"" aria-hidden=""true"">×</button>");
            sb.AppendFormat(@"    <h3 id=""{0}ModalLabel"">{1}</h3>", Name, Title);
            sb.AppendLine(@"  </div>");
            sb.AppendLine(@"  <div class=""modal-body"">");

            foreach ( var childitem in children )
            {
                sb.Append(childitem);
            }
      
            sb.AppendLine(@"      </div>");
            sb.AppendLine(@"  <div class=""modal-footer"">");
            sb.AppendLine(@"    <button class=""btn"" data-dismiss=""modal"" aria-hidden=""true"">Close</button>");
            sb.AppendLine(@"  </div>");
            sb.AppendLine(@"</div>");
            
            return MvcHtmlString.Create(sb.ToString());
        }



    }

    public enum ButtonSize
    {
        /// <summary>
        /// Default Button.
        /// </summary>
        Default,
        /// <summary>
        /// The large Button.
        /// </summary>
        Large,
        /// <summary>
        /// The small Button.
        /// </summary>
        Small,
        /// <summary>
        /// The mini Button.
        /// </summary>
        Mini
    }

    public enum ButtonStyle
    {
        /// <summary>
        /// Standard gray button with gradient.
        /// </summary>
        Default,
        /// <summary>
        /// Provides extra visual weight and identifies the primary action in a set of buttons.
        /// </summary>
        Primary,
        /// <summary>
        /// Used as an alternative to the default styles.
        /// </summary>
        Info,
        /// <summary>
        /// Indicates a successful or positive action.
        /// </summary>
        Success,
        /// <summary>
        /// Indicates caution should be taken with this action.
        /// </summary>
        Warning,
        /// <summary>
        /// Indicates a dangerous or potentially negative action.
        /// </summary>
        Danger,
        /// <summary>
        /// Alternate dark gray button, not tied to a semantic action or use.
        /// </summary>
        Inverse,
        /// <summary>
        /// Deemphasize a button by making it look like a link while maintaining button behavior.
        /// </summary>
        Link
    }

    public enum ButtonProp
    {
        /// <summary>
        /// Default nothing is added to the button.
        /// </summary>
        Default,
        /// <summary>
        /// Make buttons look unclickable by fading them back 50%.
        /// </summary>
        Disable,
        /// <summary>
        /// Create block level buttons—those that span the full width of a parent— by adding .btn-block.
        /// </summary>
        Block,
    }

    /// <summary>
    /// Converts Button Enums to the correct Css style
    /// </summary>
    public static class ButtonConverter
    {
        /// <summary>
        /// Converts Button Size to the CSS.
        /// </summary>
        /// <param name="size">The button size.</param>
        /// <returns>Button Size CSS.</returns>
        public static string ToCss(this ButtonSize size)
        {
            string result;
            switch ( size )
            {
                case ButtonSize.Default:
                    result = "";
                    break;
                case ButtonSize.Large:
                    result = "btn-large";
                    break;
                case ButtonSize.Small:
                    result = "btn-small";
                    break;
                case ButtonSize.Mini:
                    result = "btn-mini";
                    break;
                default:
                    result = "";
                    break;
            }
            return result;
        }

        /// <summary>
        /// Converts Button Style to the CSS.
        /// </summary>
        /// <param name="style">The button style.</param>
        /// <returns>Button Stlye CSS.</returns>
        public static string ToCss(this ButtonStyle style)
        {
            string result;
            switch ( style )
            {
                case ButtonStyle.Default:
                    result = "";
                    break;
                case ButtonStyle.Primary:
                    result = "btn-primary";
                    break;
                case ButtonStyle.Info:
                    result = "btn-info";
                    break;
                case ButtonStyle.Success:
                    result = "btn-success";
                    break;
                case ButtonStyle.Warning:
                    result = "btn-warning";
                    break;
                case ButtonStyle.Danger:
                    result = "btn-danger";
                    break;
                case ButtonStyle.Inverse:
                    result = "btn-inverse";
                    break;
                case ButtonStyle.Link:
                    result = "btn-link";
                    break;
                default:
                    result = "";
                    break;
            }
            return result;
        }

        /// <summary>
        /// Converts Button Properties to the CSS.
        /// </summary>
        /// <param name="prop">The button properties.</param>
        /// <returns>Button Properties CSS.</returns>
        public static string ToCss(this ButtonProp prop)
        {
            string result;
            switch ( prop )
            {
                case ButtonProp.Default:
                    result = "";
                    break;
                case ButtonProp.Disable:
                    result = "disabled ";
                    break;
                case ButtonProp.Block:
                    result = "btn-block";
                    break;
                default:
                    result = "";
                    break;
            }
            return result;
        }
    }


}
